// 字典项缓存
const Dict = {};
// 字典项格式化缓存
const DictMapping = {};

// 这是一个队列的缓存
const DictQueueCache = {};

let GetDictEvent = () => { return [] }

const DictQueueEvent = async function (type) {
    // 这是一个接口，用于请求字典项列表
    return await GetDictEvent(type);
};

// 获取字典项逻辑封装
export async function GetDict(type) {
    // 如果有字典，直接返回字典项列表
    if (type && Dict[type]) {
        return Dict[type];
    } else if (type && !Dict[type]) {
        // 如果对应字典没有被请求过，并且 队列缓存中也没有正在请求中的队列
        if (!DictQueueCache[type]) {
            // 请求字典项
            const _event = DictQueueEvent(type);
            // 在缓存中增加对应获取方法
            DictQueueCache[type] = _event;
            try {
                // 如果请求成功
                const res = await _event;
                Dict[type] = res;
                // 删除队列中的缓存对象
                delete DictQueueCache[type];
                return res;
            } catch (error) {
                // 失败也删除
                delete DictQueueCache[type];
                throw error
            }
        } else {
            return DictQueueCache[type]
        }
    }
}

// 将数组按照 value 的 key 值 格式化成 Mapping 对象的方法
// 用于处理列表很长的字典项，需要for循环很多遍的问题，提升效率
async function formatDictToMapping(options) {
    const type = options.type;
    const key = options.key || 'value';
    try {
        const res = await GetDict(type);
        const mapping = {};
        res.forEach(item => {
            mapping[item[key]] = item;
        });
        return mapping
    } catch (error) {
        console.error('格式化失败 =>', type, error)
    }
}

export const SetGetDictAjax = function (Event) {
    GetDictEvent = Event
}

export const SetDict = function (key, value) {
    Dict[key] = value;
}

export default {
    install(app) {
        app.directive('dict', async (el, binding) => {
            const type = binding.arg;
            const options = binding.value;
            let value, valueKey, showKey;
            if (Array.isArray(options)) {
                value = options[0];
                valueKey = options[1] || 'value';
                showKey = options[2] || 'label';
            } else {
                value = options;
                valueKey = 'value';
                showKey = 'label';
            };
            // 首先去 Mapping 缓存中 获取字典项格式化结果
            const CacheKey = `${type}_${valueKey}_${showKey}`;
            let _Dict = DictMapping[CacheKey]
            if (!_Dict) {
                // 如果没有缓存，去请求字典项缓存
                _Dict = DictMapping[CacheKey] = await formatDictToMapping({ type, key: valueKey })
            };
            // 获取显示名称
            try {
                const HtmlValue = _Dict[value][showKey];
                el.innerHTML = HtmlValue;
            } catch (error) {
                if (value === undefined) {
                    console.error('显示字典项失败 => 值为空', error);
                    console.error('type:', type, 'value:', value, 'valueKey:', valueKey, 'showKey:', showKey)
                } else {
                    console.error('显示字典项失败 =>', 'type:', type, 'value:', value, 'valueKey:', valueKey, 'showKey:', showKey, error)
                }
            }
        })
    }
}
